package com.lagou.util;

import com.alibaba.fastjson.JSON;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JwtTool {
    private static String SECRET = "https://doooyo.github.io";
    private static String  issure = "lee";
    // 1小时过期
    public static final int calendarField = Calendar.HOUR_OF_DAY;
    public static final int calendarInterval = 1;

    public static void main(String[] args) throws Exception {
        String token = generateJwt("duyud@qq.com", issure, SECRET);
        System.out.println(token);
        System.out.println(JSON.toJSONString(verify(token, issure, SECRET)));
    }

    /**
     * 生成JWT
     *
     * @param uid     用户ID作为jwt ID
     * @return
     */
    public static String generateJwt(String uid, String issuer, String secret) throws Exception {
        Calendar nowTime = Calendar.getInstance();
        nowTime.add(calendarField, calendarInterval);
        Date expiresDate = nowTime.getTime();

        // header Map
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        // build token
        String token = JWT.create()
                .withHeader(header)               // 头部
                .withClaim("iss", "Service") // payload负载, 可以使用claim,也可使用withXXX方式
                .withClaim("aud", "APP")
                .withClaim("uid", uid)

                .withIssuedAt(new Date())         // 签发时间
                .withIssuer(issuer)               // 签发者
                .withAudience("all")              // 受众
                .withJWTId(uid)                   // ID
                .withKeyId(uid)                   //
                .withNotBefore(new Date())        // 生效时间
                .withSubject(uid)                 // 主题
                .withExpiresAt(expiresDate)       // 过期时间(1h)
                .sign(Algorithm.HMAC256(secret)); // 签名

        return token;
    }

    /**
     * 解析JWT
     *
     * @param token 即jwt
     * @return
     * @throws Exception
     */
    public static /*Map<String, Claim>*/DecodedJWT parseJwtToken(String token, String secret) {
        DecodedJWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret)).build();
            jwt = verifier.verify(token);
            Date expiresAt = jwt.getExpiresAt();
            // 判断是否过期
            jwt = expiresAt.after(new Date()) ? jwt : null;
        } catch (Exception e) {
            e.printStackTrace();
            // token 校验失败, 抛出Token验证非法异常
        }
        //String issuer = jwt.getIssuer();
        //return jwt == null ? null : jwt.getClaims();
        return jwt;
    }

    public static boolean verify(String token, String issuer, String secret) {
        DecodedJWT jwt = null;
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret))
                    .withIssuer(issuer)
                    .build();
            jwt = verifier.verify(token);
            Date expiresAt = jwt.getExpiresAt();
            // 判断是否过期
            return expiresAt.after(new Date()) ? true : false && issuer.equalsIgnoreCase(jwt.getIssuer());
        } catch (Exception e) {
            e.printStackTrace();
            // token 校验失败, 抛出Token验证非法异常
        }
        return false;
    }
}
